/**
 * 条件构造器 用于封装查询条件
 *
 * 例如以下条件的构造方式
 * example :  [["name","=","tom,mary","and","age",">","16","and","gender","=","man"],"or",["address","=","成都"]]
 *
 *  const wrapper = new QueryWrapper();
 *  wrapper.in("name","tom,mary").gt("age",16).eq("gender","man")
 *         .newOrCondition() //设置下面的一组条件使用or连接
 *         .eq("address","成都")
 *
 * 生成的sql的where条件
 * where (name in ('tom','mary') and age > 16 and gender = 'man') or (address = '成都')
 *
 */

function QueryWrapper(pageIndex, pageSize) {
    //分页参数,查询第几页
    this.pageIndex = pageIndex || 1;
    //分页参数,每页多少条数据
    this.pageSize = pageSize || 30;

    /*
        全部条件的集合,每1组条件都是1个数组
        例如：[["age",">","16","and","gender","=","man"],"or",["address","=","成都"]]
        第1组条件：["age",">","16","and","gender","=","man"]
        第2组条件：["address","=","成都"]
    */
    this.filter = []
    //当前操作这组条件,在filter中的下标
    this.index = 0
    //排序 设置方式 ["name,asc","age,desc"]
    this.sort = []
    //需要查询的字段
    this.fields = []
    //是否把fields配置的字段,设置为排除查询的字段
    this.excludeFields = false
    //是否查询全部数据,如果设置为true, pageSize参数无效
    this.exportAll = false


}
/**
 * 获取拼接完成的查询条件
 *
 * @returns {string}
 */
QueryWrapper.prototype.getQueryObject = function () {
    let condition = {}
    condition.filter = JSON.stringify(this.filter)
    condition.sort = JSON.stringify(this.sort)
    condition.pageIndex = this.pageIndex
    condition.pageSize = this.pageSize
    condition.fields = JSON.stringify(this.fields)
    condition.excludeFields = this.excludeFields
    condition.exportAll = this.exportAll
    return condition
}
/**
 * 创建一组新的条件，并且使用 and 连接符
 *
 * @returns {QueryWrapper}
 */
QueryWrapper.prototype.newAndCondition = function () {
    this.filter.push("and")
    this.filter.push([])
    this.index = this.index + 2
    return this
}

/**
 * 创建一组新的条件，并且使用 or 连接符
 *
 * @returns {QueryWrapper}
 */
QueryWrapper.prototype.newOrCondition = function () {
    this.filter.push("or")
    this.filter.push([])
    this.index = this.index + 2
    return this
}

/**
 * 使用or连接符
 *
 * @returns {QueryWrapper}
 */
QueryWrapper.prototype.or = function () {
    let wrapper = this.filter[this.index]
    if (wrapper === undefined) {
        return this
    }

    if (wrapper.length > 0) {
        const str = wrapper[wrapper.length - 1]
        if (str !== "and" && str !== "or") {
            wrapper.push("or")
        }
    }
    return this;
}

/**
 * 设置查询条件
 *
 * @param field 字段
 * @param connector 条件连接符
 * @param value 值
 */
QueryWrapper.prototype.setCondition = function (field, connector, value) {
    let wrapper = this.filter[this.index]
    if (wrapper === undefined) {
        wrapper = []
        this.filter[this.index] = wrapper
    }
    if (wrapper.length > 0) {
        const str = wrapper[wrapper.length - 1]
        if (str !== "and" && str !== "or") {
            wrapper.push("and")
        }
    }
    wrapper.push(field)
    wrapper.push(connector)
    wrapper.push(value)
    return this;
}
/**
 * 等于
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.eq = function (field, value) {
    return this.setCondition(field, "=", value)
}
/**
 * 不等于
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.ne = function (field, value) {
    return this.setCondition(field, "!=", value)
}
/**
 * 大于
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.gt = function (field, value) {
    return this.setCondition(field, ">", value)
}
/**
 * 大于等于
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.ge = function (field, value) {
    return this.setCondition(field, ">=", value)
}
/**
 * 小于
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.lt = function (field, value) {
    return this.setCondition(field, "<", value)
}
/**
 * 小于等于
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.le = function (field, value) {
    return this.setCondition(field, "<=", value)
}
/**
 * in value接收多个参数 使用英文逗号 , 分隔
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.in = function (field, value) {
    return this.setCondition(field, "in", value)
}
/**
 * not in value接收多个参数 使用英文逗号 , 分隔
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.notIn = function (field, value) {
    return this.setCondition(field, "not_in", value)
}
/**
 * 模糊匹配
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.like = function (field, value) {
    return this.setCondition(field, "like", value)
}
/**
 * 空
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.isNull = function (field, value) {
    return this.setCondition(field, "none", '')
}
/**
 * 不为空
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.ge = function (field, value) {
    return this.setCondition(field, "not_none", value)
}

/**
 * between区间 value接收两个参数 使用英文逗号 , 分隔
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.between = function (field, value) {
    return this.setCondition(field, "between", value)
}
/**
 * not between区间 value接收两个参数 使用英文逗号 , 分隔
 *
 * @param field 字段
 * @param value 值
 */
QueryWrapper.prototype.notBetween = function (field, value) {
    return this.setCondition(field, "not_between", value)
}

/**
 * 升序排序
 *
 * @param field
 */
QueryWrapper.prototype.orderByAsc = function (field) {
    if (this.sort.length > 0) {
        this.sort = []
    }
    this.sort.push(field + ",asc")
    return this
}

/**
 * 降序排序
 *
 * @param field
 */
QueryWrapper.prototype.orderByDesc = function (field) {
    if (this.sort.length > 0) {
        this.sort = []
    }
    this.sort.push(field + ",desc")
    return this
}

/**
 * elementUI排序
 *
 * @param field
 * @param order 排序方式 elementUI的表格的两种枚举  ascending || descending
 */
QueryWrapper.prototype.orderBy = function (field, order) {
    if (order === "ascending") {
        this.orderByAsc(field)
    } else if (order === "descending") {
        this.orderByDesc(field)
    }
    return this
}
/**
 * 设置分页参数
 *
 * @param pageIndex 当前页
 * @param pageSize 每页多少条数据
 */
QueryWrapper.prototype.setPageParams = function (pageIndex, pageSize) {
    if (pageIndex > 0) {
        this.pageIndex = pageIndex;
    }
    if (pageSize > 0) {
        this.pageSize = pageSize;
    }
    return this
}

/**
 * 设置分页参数
 *
 * @param pageIndex 当前页
 */
QueryWrapper.prototype.setPageIndex = function (pageIndex) {
    if (pageIndex > 0) {
        this.pageIndex = pageIndex;
    }
    return this
}

/**
 * 设置分页参数
 *
 * @param pageSize 每页多少条数据
 */
QueryWrapper.prototype.setPageSize = function (pageSize) {
    if (pageSize > 0) {
        this.pageSize = pageSize;
    }
    return this
}

/**
 * 设置 [需要  || 不需要] 查询的字段
 *
 * @param excludeFields 是否把fields配置的字段,设置为排除查询的字段
 * @param fields 需要查询的字段
 */
QueryWrapper.prototype.setFields = function (excludeFields, fields) {
    this.excludeFields = excludeFields || false;
    if (this.fields.length > 0) {
        this.fields = []
    }
    for (const field in fields) {
        if (field && field.trim() !== '') {
            this.fields.push(field)
        }
    }
    return this
}
/**
 * 取消分页,查询全部数据
 *
 * @param exportAll exportAll
 */
QueryWrapper.prototype.setExportAll = function (exportAll) {
    this.exportAll = exportAll || true;
    return this
}

// let person1 = new QueryWrapper("litangmm","man");
// let person2 = new Person("littleM","woman");
// person1.sayName();
// person2.saySex();
